/**
 * 建模工程
 */
import MavenProjectUtil from '@/logic/maven/util/project.js';

export default class ModelingProject {

    /**
     * 对应的Maven工程对象
     * @type {Object}
     */
    maven = null;
    /**
     * 包含的应用清单
     * @type {[ModelingApp]}
     */
    apps = [];

    constructor(maven) {
        this.maven = maven;
    }

    /**
     * 判断是否为单体架构
     * @returns {boolean|undefined} true:单体架构, false:微服务架构, undefined:未决
     */
    isSingleArch() {
        return MavenProjectUtil.isSingleArch(this.maven);
    }

    findApp(appName) {
        if (appName) {
            for (let app of this.apps) {
                if (app.name === appName) {
                    return app;
                }
            }
        }
        return null;
    }

    findClass(appName, clazz, findInDependencies, toOrigin) {
        for (let app of this.apps) {
            if (!appName || appName === app.name) {
                let c = app.findClass(clazz, findInDependencies, toOrigin);
                if (c) {
                    if (!appName) {
                        c.appName = app.name;
                    }
                    return c;
                }
            }
        }
        return undefined;
    }

    loopSubClasses(superClass, consumer) {
        for (let app of this.apps) {
            app.loopSubClasses(superClass, consumer);
        }
    }

    getSubClassTree(clazz, subsFieldName = 'subs') {
        const getSubClasses = superClassId => {
            let subClasses = [];
            if (superClassId) {
                for (let app of this.apps) {
                    for (let subClass of app.classes) {
                        if (subClass.superClassId === superClassId) {
                            subClass = subClass.clone();
                            subClass.appName = app.name;
                            subClasses.push(subClass);
                        }
                    }
                }
                for (let subClass of subClasses) {
                    subClass[subsFieldName] = getSubClasses(subClass.id);
                }
            }
            return subClasses;
        }
        clazz = this.findClass(null, clazz);
        return getSubClasses(clazz?.id);
    }

    /**
     * 获取在继承体系中从顶级父类定位到指定类的类链
     * @param clazz 类
     * @param findInDependencies 是否在依赖中查找
     * @param withSelf 结果中是否要包含指定类自身
     */
    getSuperClassChain(clazz, findInDependencies = false, withSelf = false) {
        let chain = [];
        if (clazz) {
            let selfClass = this.findClass(null, clazz, findInDependencies, true);
            let superClass = this.findClass(null, selfClass.superClassId, findInDependencies, true);
            while (superClass) {
                chain.unshift(superClass);
                superClass = this.findClass(null, superClass.superClassId, findInDependencies, true);
            }
            if (withSelf) {
                chain.push(selfClass);
            }
        }
        return chain;
    }

}
